package org.bronycorps.mlptss.domain.actor;

import org.bronycorps.mlptss.MlpTss;
import org.bronycorps.mlptss.domain.controller.AbstractController;
import org.bronycorps.mlptss.domain.controller.SpecialMissileController;
import org.bronycorps.mlptss.domain.layer.MissileLayer;
import org.bronycorps.mlptss.domain.layer.Track;
import org.bronycorps.mlptss.domain.model.AbstractActorModel;
import org.bronycorps.mlptss.domain.model.event.StateChangeEvent;
import org.bronycorps.mlptss.domain.model.event.StateChangeEventListener;
import org.bronycorps.mlptss.manager.TrajectFactory;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Vector2;

public class SpecialMissileActor extends AbstractActor implements
		StateChangeEventListener {

	private final SpecialMissileController missileController;
	private final Track track;

	public SpecialMissileActor(SpecialMissileController controller, Track track) {
		super();
		this.missileController = controller;
		this.track = track;

		this.missileController.getModel().addListener(this);

		updateAnimation();

	}

	@Override
	public void act(float delta) {
		super.act(delta);

		switch (this.missileController.getModel().getState()) {
		case EXPLODE:
			if (this.currentAnimation.isAnimationFinished(this.currentTime)) {
				terminate();
			}
			break;
		default:
			break;
		}
	}

	@Override
	protected AbstractController getController() {
		return this.missileController;
	}

	public SpecialMissileController getMissile() {
		return this.missileController;
	}

	public int getMissileType() {
		return this.missileController.getModel().getMissileType();
	}

	@Override
	public AbstractActorModel getModel() {
		return this.missileController.getModel();
	}

	@Override
	protected Vector2 getModelPosition() {
		return getModel().getPosition();
	}

	@Override
	public Track getTrack() {
		return this.track;
	}

	@Override
	public void onStateChange(StateChangeEvent event) {
		switch (event.getSpecialMissile().getState()) {
		case EXPLODE:
			// when exploding, the entity must not move anymore
			TrajectFactory.getInstance().clearTweens(this);
			switchAnimation(this.missileController.getModel()
					.getExplodeAnimation());
			break;
		default:
			break;
		}
	}

	public void setInitialPosition(float x, float y) {
		getModelPosition().set(x, y);
		updateVisualPosition();
	}

	public void setInitialPosition(Vector2 position) {
		getModelPosition().set(position);
		updateVisualPosition();
	}

	public void setMissileType(int missileType) {
		this.missileController.getModel().setMissileType(missileType);
		updateAnimation();
	}

	public void setModelPosition(float x, float y) {
		getModel().getPosition().set(x, y);
		Gdx.app.log(MlpTss.LOG, "set actor position : "
				+ getModel().getPosition());
	}

	public void terminate() {
		((MissileLayer) getParent()).removeSpecialMissile(this);
	}

	private void updateAnimation() {
		this.currentAnimation = this.missileController.getModel()
				.getDefaultAnimation();

		setDrawable(this.currentAnimation.getDrawableKeyFrame(this.currentTime));
		setWidth(getPrefWidth());
		setHeight(getPrefHeight());
		setOrigin(getModelOrigin().x, getModelOrigin().y);

		this.hitBox.setWidth(getBounds().width);
		this.hitBox.setHeight(getBounds().height);
	}

}
